Module('Phosphor.Events', function () {
    var jsonp_uid = 0, 
        Promise = this.Promise;

    Promise.JSONP = function (opt) {
        var url     = opt.url,
            data    = opt.data || {},
            padding = opt.data || "callback",
            timeout = opt.timeout || 10000,
            timer   = null,
            head    = document.getElementsByTagName('HEAD')[0],
            key     = "jsonp_callback_" + jsonp_uid,
            script  = document.createElement('script'),
            encode  = window.encodeURIComponent,
            promise = this,
            query_string, resolve, k;

        query_string = "";
        for (k in data) if (data.hasOwnProperty(k)) {
            query_string += (encode(k) + "=" + encode(value) + "&");
        }

        script.type = "text/javascript";
        script.src = [url, '?', query_string, encode(padding), '=', encode(key)].join('');

        resolve = function (value, succeeded) {
            delete window[key]; 

            if (script.parentNode === head) {
                head.removeChild(script);
            }

            window.clearTimeout(timer);

            if (succeeded) {
                promise.resolve(value);
            } else {
                promise.fail();
            }
        };

        window[key] = function (data) {
            resolve(data, true);
        };

        timer = window.setTimeout(function () {
            resolve(null, false);
        }, timeout);

        jsonp_uid++;

        head.appendChild(script);
    };

    Promise.JSONP.prototype = Object.create(Promise.prototype);
}.call(null));
